//
//  NSObject+KTableModel.m
//  MengLiao
//
//  Created by xiuxin on 2022/7/15.
//  Copyright © 2022 ZHBen. All rights reserved.
//

#import "NSObject+KTableModel.h"
#import <objc/runtime.h>

@implementation NSObject(KCellModel)

- (NSString *)kCellIdentifier
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKCellIdentifier:(NSString *)kCellIdentifier
{
    objc_setAssociatedObject(self, @selector(kCellIdentifier), kCellIdentifier, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (KCellConfigBlock)kCellConfigBlock
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKCellConfigBlock:(KCellConfigBlock)kCellConfigBlock
{
    objc_setAssociatedObject(self, @selector(kCellConfigBlock), kCellConfigBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (KCellSelectBlock)kCellSelectBlock
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKCellSelectBlock:(KCellSelectBlock)kCellSelectBlock
{
    objc_setAssociatedObject(self, @selector(kCellSelectBlock), kCellSelectBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSNumber *)kCellHeight
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKCellHeight:(NSNumber *)kCellHeight
{
    objc_setAssociatedObject(self, @selector(kCellHeight), kCellHeight, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSNumber *)kCellCanDelete
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKCellCanDelete:(NSNumber *)kCellCanDelete
{
    objc_setAssociatedObject(self, @selector(kCellCanDelete), kCellCanDelete, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSNumber *)kCellCanMove
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKCellCanMove:(NSNumber *)kCellCanMove
{
    objc_setAssociatedObject(self, @selector(kCellCanMove), kCellCanMove, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSArray<UITableViewRowAction *> *)kActionList
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKActionList:(NSArray<UITableViewRowAction *> *)kActionList
{
    objc_setAssociatedObject(self, @selector(kActionList), kActionList, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

@implementation NSObject(KCellDelete)

- (KCellDeleteConfirmBlock)kCellDeleteConfirmBlock
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKCellDeleteConfirmBlock:(KCellDeleteConfirmBlock)kCellDeleteConfirmBlock
{
    objc_setAssociatedObject(self, @selector(kCellDeleteConfirmBlock), kCellDeleteConfirmBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end

@implementation NSObject(KSectionModel)

- (NSString *)kSectionHeaderIdentifier
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKSectionHeaderIdentifier:(NSString *)kSectionHeaderIdentifier
{
    objc_setAssociatedObject(self, @selector(kSectionHeaderIdentifier), kSectionHeaderIdentifier, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)kSectionFooterIdentifier
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKSectionFooterIdentifier:(NSString *)kSectionFooterIdentifier
{
    objc_setAssociatedObject(self, @selector(kSectionFooterIdentifier), kSectionFooterIdentifier, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)kSectionIndexTitle
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKSectionIndexTitle:(NSString *)kSectionIndexTitle
{
    objc_setAssociatedObject(self, @selector(kSectionIndexTitle), kSectionIndexTitle, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (KSectionConfigBlock)kSectionHeaderConfigBlock
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKSectionHeaderConfigBlock:(KSectionConfigBlock)kSectionHeaderConfigBlock
{
    objc_setAssociatedObject(self, @selector(kSectionHeaderConfigBlock), kSectionHeaderConfigBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (KSectionConfigBlock)kSectionFooterConfigBlock
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKSectionFooterConfigBlock:(KSectionConfigBlock)kSectionFooterConfigBlock
{
    objc_setAssociatedObject(self, @selector(kSectionFooterConfigBlock), kSectionFooterConfigBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSNumber *)kSectionHeaderHeight
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKSectionHeaderHeight:(NSNumber *)kSectionHeaderHeight
{
    objc_setAssociatedObject(self, @selector(kSectionHeaderHeight), kSectionHeaderHeight, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSNumber *)kSectionFooterHeight
{
    return objc_getAssociatedObject(self, _cmd);
}

- (void)setKSectionFooterHeight:(NSNumber *)kSectionFooterHeight
{
    objc_setAssociatedObject(self, @selector(kSectionFooterHeight), kSectionFooterHeight, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

@end

@interface KCommonTableModel()

@property (weak,nonatomic) id modelForCompare;

@end

@implementation KCommonTableModel : NSObject

+ (KCommonTableModel *)cellModel:(id)model identifier:(NSString *)identifier
{
    return [[self alloc] initWithCellModel:model identifier:identifier];
}

- (id)initWithCellModel:(id)model identifier:(NSString *)identifier
{
    self = [super init];
    if (self)
    {
        _model = model;
        _modelForCompare = model ?: [NSNull null];
        self.kCellIdentifier = identifier;
    }
    return self;
}

+ (KCommonTableModel *)sectionModel:(id)model headerIdentifier:(NSString *)headerIdentifier footerIdentifier:(NSString *)footerIdentifier
{
    return [[self alloc] initWithSectionModel:model headerIdentifier:headerIdentifier footerIdentifier:footerIdentifier];
}

- (id)initWithSectionModel:(id)model headerIdentifier:(NSString *)headerIdentifier footerIdentifier:(NSString *)footerIdentifier
{
    self = [super init];
    if (self)
    {
        _model = model;
        _modelForCompare = model ?: [NSNull null];
        self.kSectionHeaderIdentifier = headerIdentifier;
        self.kSectionFooterIdentifier = footerIdentifier;
    }
    return self;
}

- (BOOL)isEqual:(id)object
{
    if ([self kCellIdentifier])
    {
        if (![[object kCellIdentifier] isEqualToString:[self kCellIdentifier]])
        {
            return NO;
        }
    }
    else if ([self kSectionHeaderIdentifier])
    {
        if (![[object kSectionHeaderIdentifier] isEqualToString:[self kSectionHeaderIdentifier]])
        {
            return NO;
        }
    }
    else if ([self kSectionFooterIdentifier])
    {
        if (![[object kSectionFooterIdentifier] isEqualToString:[self kSectionFooterIdentifier]])
        {
            return NO;
        }
    }
    if (_comparator)
    {
        return _comparator(self,object) == NSOrderedSame;
    }
//    if ([self isKindOfClass:[KCommonTableModel class]] || [object isKindOfClass:[KCommonTableModel class]])
//    {
//        return NO;
//    }
    return _modelForCompare == [object modelForCompare] || [_modelForCompare isEqual:[object modelForCompare]] || [super isEqual:object];
}

+ (NSArray<KCommonTableModel *> *)arrayModelListWithDataList:(NSArray *)dataList countPerCell:(NSInteger)count identifier:(NSString *)identifier
{
    if (dataList.count > 0 && count > 0)
    {
        NSInteger cellCount = dataList.count / count;
        NSMutableArray<KCommonTableModel *> * modelList = [NSMutableArray arrayWithCapacity:cellCount + 1];
        for (NSInteger index = 0; index < cellCount; index++)
        {
            NSArray * listForCell = [dataList subarrayWithRange:NSMakeRange(index * count, count)];
            [modelList addObject:[KCommonTableModel cellModel:listForCell identifier:identifier]];
        }
        NSInteger leftCount = dataList.count - cellCount * count;
        if (leftCount > 0)
        {
            NSArray * lastListForCell = [dataList subarrayWithRange:NSMakeRange(cellCount * count, leftCount)];
            [modelList addObject:[KCommonTableModel cellModel:lastListForCell identifier:identifier]];
        }
        return modelList;
    }
    return nil;
}

@end
